package com.system.security.jwt;

import com.component.domain.MUserToken;
import com.component.service.MUserTokenService;
import com.system.config.JWTConfig;
import com.system.config.SpringContextUtils;
import com.system.security.domain.SelfUserEntity;
import com.alibaba.fastjson.JSONObject;
import com.system.util.CookieUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author Xiongx
 * @version 1.0
 * @date 2021/6/11 15:13
 * @since JDK 1.8
 */
@Slf4j
public class JWTAuthenticationTokenFilter extends BasicAuthenticationFilter {

    public JWTAuthenticationTokenFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 获取请求头中JWT的Token
        String token="";
        String tokenHeader = request.getHeader(JWTConfig.tokenHeader);
        if(tokenHeader!=null){
            // 截取JWT前缀
            token = tokenHeader.replace(JWTConfig.tokenPrefix, "");
        }
        if(tokenHeader==null){
            System.out.println(tokenHeader);
            Cookie[] cookies=request.getCookies();
            Cookie cookie=CookieUtils.getCookieByName(cookies,JWTConfig.tokenHeader);
            if(cookie != null){
                token = cookie.getValue();
                token=token.replace(JWTConfig.tokenPrefix,"");
            }
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(token)) {
            try {
                // 解析JWT
                Claims claims = Jwts.parser()
                        .setSigningKey(JWTConfig.secret)
                        .parseClaimsJws(token)
                        .getBody();
                // 使用签发时间
                Date date=claims.getIssuedAt();
                System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
                Date current=new Date();
                System.out.println(current.getTime() - date.getTime());
                if((current.getTime() - date.getTime()) > 10000){
                    MUserTokenService mUserTokenService=SpringContextUtils.getBean(MUserTokenService.class);
                    MUserToken mUserToken=mUserTokenService.getMuserTokenByToken(JWTConfig.tokenPrefix+token);
                    if(mUserToken!=null){
                        pass(token,claims,response);
                    }
                }else {
                    pass(token,claims,response);
                }
            } catch (ExpiredJwtException e){
                log.info("Token过期");
            } catch (Exception e) {
                log.info("Token无效");
            }
        }
        filterChain.doFilter(request, response);
        return;
    }


    public void pass(String token,Claims claims,HttpServletResponse response){
        String userId=claims.getId();
        String username = claims.getSubject();
        if(!StringUtils.isEmpty(username)&&!StringUtils.isEmpty(userId)) {
            // 获取角色
            List<GrantedAuthority> authorities = new ArrayList<>();
            String authority = claims.get("authorities").toString();
            if(!StringUtils.isEmpty(authority)){
                List<Map<String,String>> authorityMap = JSONObject.parseObject(authority, List.class);
                for(Map<String,String> role : authorityMap){
                    if(!StringUtils.isEmpty(role)) {
                        authorities.add(new SimpleGrantedAuthority(role.get("authority")));
                    }
                }
            }
            //组装参数
            SelfUserEntity selfUserEntity = new SelfUserEntity();
            selfUserEntity.setUsername(claims.getSubject());
            selfUserEntity.setUserId(Long.parseLong(claims.getId()));
            selfUserEntity.setAuthorities(authorities);

            //如果设置此项失败，则将不允许登录
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(selfUserEntity, userId, authorities);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            Cookie cookie = new Cookie(JWTConfig.tokenHeader, token);

            // 设置Cookie的其他属性（可选）
            cookie.setMaxAge(3600); // 设置Cookie的生命周期，单位为秒
            cookie.setPath("/"); // 设置Cookie的路径
            // 其他属性，如：cookie.setDomain("domain.com");
            // 将Cookie添加到响应中
            response.addCookie(cookie);
        }
    }
}
